home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 2000-1 drscholl@users.sourceforge.net
- This is free software distributed under the terms of the
- GNU Public License. See the file COPYING for details.
-
- $Id: list_users.c,v 1.25 2001/02/15 08:39:45 drscholl Exp $ */
-
- #include <string.h>
- #include <ctype.h>
- #include "opennap.h"
- #include "debug.h"
-
- /* packet contains: <channel> */
- HANDLER (list_users)
- {
- CHANNEL *chan;
- LIST *list;
- CHANUSER *chanUser;
-
- (void) tag;
- (void) len;
- ASSERT (validate_connection (con));
- CHECK_USER_CLASS ("list_users");
- chan = hash_lookup (Channels, pkt);
- if (!chan)
- {
- nosuchchannel (con);
- return;
- }
- ASSERT (validate_channel (chan));
- /* make sure this user is on the channel */
- if (list_find (con->user->channels, chan) == 0)
- {
- send_cmd (con, MSG_SERVER_NOSUCH, "you're not on channel %s",
- chan->name);
- return;
- }
-
- for (list = chan->users; list; list = list->next)
- {
- chanUser = list->data;
- ASSERT (chanUser->magic == MAGIC_CHANUSER);
- send_cmd (con, MSG_SERVER_NAMES_LIST /* 825 */ , "%s %s %d %d",
- chan->name, chanUser->user->nick, chanUser->user->shared,
- chanUser->user->speed);
- }
-
- send_cmd (con, MSG_SERVER_NAMES_LIST_END /* 830 */ , "");
- }
-
- #define ON_GFLAG_ELITE 1
- #define ON_GFLAG_ADMIN 2
- #define ON_GFLAG_MODERATOR 4
- #define ON_GFLAG_LEECH 8
- #define ON_GFLAG_MUZZLED 16
- #define ON_GFLAG_CLOAKED 32
- #define ON_GFLAG_USERS 64
- #define ON_GFLAG_CHANNEL 128
- #define ON_GFLAG_USERIP 256
-
- struct guldata
- {
- int flags;
- char *server;
- char *chan;
- unsigned int ip;
- unsigned int mask;
- CONNECTION *con;
- };
-
- static void
- global_user_list_cb (USER * user, struct guldata *data)
- {
- ASSERT (validate_user (user));
- ASSERT (data != 0);
- if (data->flags)
- {
- /* selectively display users based on user level/muzzle/cloak */
- if (!
- (((data->flags & ON_GFLAG_ADMIN) && user->level == LEVEL_ADMIN)
- || ((data->flags & ON_GFLAG_ELITE) && user->level == LEVEL_ELITE)
- || ((data->flags & ON_GFLAG_MODERATOR)
- && user->level == LEVEL_MODERATOR)
- || ((data->flags & ON_GFLAG_USERS) && user->level == LEVEL_USER)
- || ((data->flags & ON_GFLAG_LEECH) && user->level == LEVEL_LEECH)
- || ((data->flags & ON_GFLAG_MUZZLED) && user->muzzled)
- || ((data->flags & ON_GFLAG_CLOAKED) && user->cloaked)
- || ((data->flags & ON_GFLAG_USERIP) && (user->ip & data->mask) == (data->ip & data->mask))))
- return;
- }
- if (data->server && *data->server != '*' &&
- strcasecmp (data->server, user->server) != 0)
- return; /* no match */
- send_cmd (data->con, MSG_SERVER_GLOBAL_USER_LIST, "%s %s", user->nick,
- my_ntoa (BSWAP32 (user->ip)));
- }
-
-
- /* 831 [server] [flags] */
- HANDLER (global_user_list)
- {
- struct guldata data;
- char *flag, *ip;
-
- ASSERT (validate_connection (con));
- (void) len;
- CHECK_USER_CLASS ("global_user_list");
- if (con->user->level < LEVEL_MODERATOR)
- {
- permission_denied (con);
- return;
- }
- memset(&data,0,sizeof(data));
- data.con = con;
- data.server = next_arg (&pkt);
-
- flag = next_arg (&pkt);
- while (flag && *flag)
- {
- switch (*flag)
- {
- case 'e':
- data.flags |= ON_GFLAG_ELITE;
- break;
- case 'a':
- data.flags |= ON_GFLAG_ADMIN;
- break;
- case 'm':
- data.flags |= ON_GFLAG_MODERATOR;
- break;
- case 'u':
- data.flags |= ON_GFLAG_USERS;
- break;
- case 'l':
- data.flags |= ON_GFLAG_LEECH;
- break;
- case 'z':
- data.flags |= ON_GFLAG_MUZZLED;
- break;
- case 'i':
- data.flags |= ON_GFLAG_USERIP;
- ip = next_arg (&pkt);
- if (!ip || !is_address (ip, &data.ip, &data.mask))
- goto guser_end;
- break;
- case 'c':
- data.flags |= ON_GFLAG_CLOAKED;
- break;
- case 'C':
- data.flags |= ON_GFLAG_CHANNEL;
- data.chan = next_arg (&pkt);
- break;
- }
- flag++;
- if (!*flag)
- flag = next_arg (&pkt);
- }
-
- if (data.flags & ON_GFLAG_CHANNEL)
- {
- CHANNEL *chan;
- LIST *list;
- CHANUSER *chanUser;
-
- /* this needs to be unset otherwise global_user_list_cb() will
- * bomb out.
- */
- data.flags &= ~ON_GFLAG_CHANNEL;
- if (data.chan)
- {
- chan = hash_lookup (Channels, data.chan);
- if (chan)
- {
- for (list = chan->users; list; list = list->next)
- {
- chanUser = list->data;
- ASSERT (chanUser->magic == MAGIC_CHANUSER);
- global_user_list_cb (chanUser->user, &data);
- }
- }
- else
- nosuchchannel (con);
- }
- }
- else
- hash_foreach (Users, (hash_callback_t) global_user_list_cb, &data);
- guser_end:
- send_cmd (con, tag, ""); /* end of list */
- }
-